#include <Poco/Net/HTTPServerRequestImpl.h>
#include <Poco/Net/HTTPServerResponseImpl.h>
#include <Poco/Net/HTTPRequestHandler.h>
#include <Poco/Net/HTTPRequestHandlerFactory.h>
#include <Poco/Net/HTTPServerParams.h>
#include <Poco/Net/NetException.h>
#include <Poco/Exception.h>
#include <Poco/Net/SSLManager.h>
#include <Poco/Net/ConsoleCertificateHandler.h>
#include <chrono>
#include <sstream>
#include "../../include/CLink/Server/Server.h"

namespace CLink
{
namespace Server
{
// 默认服务器配置
static const ServerConfig DEFAULT_CONFIG = {
    8080,  // port
    443,  // securePort
    16,    // maxThreads
    100,   // maxQueued
    true,  // keepAlive
    30,    // timeout
    false, // enableHttps
    "",    // certFile
    "",    // keyFile
    ""     // caLocation
};

// 请求处理器类
class RequestHandler : public Poco::Net::HTTPRequestHandler
{
public:
    RequestHandler(Server &server) : _server(server) {}

    void handleRequest(Poco::Net::HTTPServerRequest &pocoRequest, Poco::Net::HTTPServerResponse &pocoResponse) override
    {
        _server.getRouter()->handleRequest(pocoRequest, pocoResponse);
    }

private:
    Server &_server;
};

// 请求处理器工厂类
class RequestHandlerFactory : public Poco::Net::HTTPRequestHandlerFactory
{
public:
    RequestHandlerFactory(Server &server) : _server(server) {}

    Poco::Net::HTTPRequestHandler *createRequestHandler(const Poco::Net::HTTPServerRequest &) override
    {
        static int a = 0;
        std::cout << "new coonection id=" << ++a << std::endl;
        return new RequestHandler(_server);
    }

private:
    Server &_server;
};

void Server::setLogger(Poco::Logger& logger)
{
    _pLogger = &logger;
}

// 构造函数
Server::Server() : _initialized(false),
                    _running(false),
                    _config(DEFAULT_CONFIG),
                    _httpServer(nullptr),
                    _pLogger(nullptr)
{

}

// 析构函数
Server::~Server()
{
    if (_running)
    {
        stop();
    }
}

// 初始化服务器
void Server::initialize(const ServerConfig &config)
{
    std::lock_guard<std::mutex> lock(_mutex);

    _pLogger->warning("Server already initialized");
    _config = config;
    _initialized = true;

    _pLogger->information("Server initialized with port " + std::to_string(_config.port));
}

// 启动服务器
void Server::start()
{
    std::lock_guard<std::mutex> lock(_mutex);

    if (!_initialized)
    {
        throw std::runtime_error("Server not initialized");
    }

    if (_running)
    {
        _pLogger->warning("Server already running");
        return;
    }

    try
    {
        // 创建HTTP服务器参数
        auto params = new Poco::Net::HTTPServerParams;
        params->setMaxQueued(_config.maxQueued);
        params->setMaxThreads(_config.maxThreads);
        params->setKeepAlive(_config.keepAlive);
        params->setTimeout(_config.timeout);

        // 创建请求处理器工厂
        auto factory = new RequestHandlerFactory(*this);

        // 如果启用HTTPS，创建HTTPS服务器
        if (_config.enableHttps)
        {
            if (_config.certFile.empty() || _config.keyFile.empty())
            {
                throw std::runtime_error("HTTPS enabled but certificate or key file not provided");
            }
            //
            Poco::Net::initializeSSL();
            // 创建安全套接字上下文
            Poco::Net::Context::Ptr context = new Poco::Net::Context(
                Poco::Net::Context::SERVER_USE,
                _config.keyFile,
                _config.certFile,
                _config.caLocation,
                Poco::Net::Context::VERIFY_NONE
                //2,
                //true,
                //"ECDHE-RSA-AES256-GCM-SHA384:TLS_AES_256_GCM_SHA384"
            );

            context->disableProtocols(
                Poco::Net::Context::PROTO_SSLV2 |
                Poco::Net::Context::PROTO_SSLV3 |
                Poco::Net::Context::PROTO_TLSV1 |
                Poco::Net::Context::PROTO_TLSV1_1
            );

            Poco::Net::SSLManager::instance().initializeServer(
                nullptr,
                new Poco::Net::ConsoleCertificateHandler(false),
                context
            );

            // 创建安全服务器套接字
            Poco::Net::SecureServerSocket secureSocket(_config.securePort);

            Poco::Logger& logger = Poco::Logger::get("SSL");
            logger.setLevel(Poco::Message::PRIO_DEBUG);

            // 创建HTTPS服务器参数
            auto secureParams = new Poco::Net::HTTPServerParams;
            secureParams->setMaxQueued(_config.maxQueued);
            secureParams->setMaxThreads(_config.maxThreads);
            secureParams->setKeepAlive(_config.keepAlive);
            secureParams->setTimeout(_config.timeout);

            // 创建HTTPS服务器
            _httpServer = std::make_unique<Poco::Net::HTTPServer>(factory, secureSocket, secureParams);
            _pLogger->information("HTTPS server starting on port " + std::to_string(_config.securePort));
        }
        else
        {
            // 创建HTTP服务器
            Poco::Net::ServerSocket socket(_config.port);
            _httpServer = std::make_unique<Poco::Net::HTTPServer>(factory, socket, params);
            _pLogger->information("HTTP server starting on port " + std::to_string(_config.port));
        }
        _httpServer->start();
        // 启动HTTP服务器
        _running = true;

        _pLogger->information("Server started successfully");
    }
    catch (const Poco::Net::NetException &ex)
    {
        _pLogger->error("Network error while starting server: " + std::string(ex.what()));
        throw;
    }
    catch (const std::exception &ex)
    {
        _pLogger->error("Error starting server: " + std::string(ex.what()));
        throw;
    }
}

// 停止服务器
void Server::stop()
{
    std::lock_guard<std::mutex> lock(_mutex);

    if (!_running)
    {
        _pLogger->warning("Server not running");
        return;
    }

    try
    {
        _pLogger->information("Stopping server...");

        // 停止HTTP服务器
        if (_httpServer)
        {
            _httpServer->stop();
            _httpServer.reset();
        }
        _running = false;

        _pLogger->information("Server stopped successfully");
    }
    catch (const std::exception &ex)
    {
        _pLogger->error("Error stopping server: " + std::string(ex.what()));
        throw;
    }
}

// 重启服务器
void Server::restart()
{
    _pLogger->information("Restarting server...");

    if (_running)
    {
        stop();
    }

    start();
}

// 获取路由器
CLink::Router::Router* Server::getRouter()
{
    return &_router;
}

// 获取服务器配置
const ServerConfig &Server::getConfig() const
{
    return _config;
}

// 设置服务器配置
void Server::setConfig(const ServerConfig &config)
{
    std::lock_guard<std::mutex> lock(_mutex);

    if (_running)
    {
        throw std::runtime_error("Cannot change configuration while server is running");
    }

    _config = config;
}

// 检查服务器是否正在运行
bool Server::isRunning() const
{
    return _running;
}

}
}